using System;
using System.Collections.Generic;
using CatLib.Container;
using GameFramework.Update;

namespace GameFramework.Gameplay
{
    /// <summary>
    /// 玩法系统容器实现
    /// </summary>
    internal sealed class GameplaySystemContainer : IGameplaySystemContainer
    {
        private const string Tag = "GameplaySystem";

        private readonly List<IFixedUpdate> m_FixedUpdates = new List<IFixedUpdate>();

        public void Initialize()
        {
            var systems = CatLib.App.That.Tagged(Tag);
            if (systems == null || systems.Length == 0)
                return;

            foreach (var system in systems)
            {
                if (system is IFixedUpdate fixedUpdate)
                    m_FixedUpdates.Add(fixedUpdate);
            }
        }

        public void Dispose()
        {
            m_FixedUpdates.Clear();
            
            CatLib.App.That.UnbindTag(Tag);
        }

        public void OnFixedUpdate(float elapseSeconds, float realElapseSeconds)
        {
            foreach (var fixedUpdate in m_FixedUpdates)
            {
                try
                {
                    fixedUpdate.OnFixedUpdate(elapseSeconds, realElapseSeconds);
                }
                catch (Exception e)
                {
                    Log.Exception(e);
                }
            }
        }

        public void Add<T, TConcrete>() where T : IGameplaySystem where TConcrete : class, T
        {
            CatLib.App.That.Singleton<T, TConcrete>().Tag(Tag);
        }
    }
}